package TuiLayer;

import java.util.Date;
import java.text.DateFormat;
import java.text.SimpleDateFormat;

import ControlLayer.PurchaseCtr;
import ControlLayer.ProductCtr;
import ControlLayer.CustomerCtr;
import ModelLayer.Purchase;
import ModelLayer.Product;
import ModelLayer.Customer;
import ModelLayer.Employee;
import ModelLayer.LineItem;

import java.util.Scanner;

/**
 * Vestbjerg project
 * @GroupB2 (UCN - Computer Science DMAJ0914) 
 */
public class PurchaseUI
{
    // instance variables
    private PurchaseCtr purchaseCtr;
    private ProductCtr productCtr;
    private CustomerCtr customerCtr;
    private Purchase purchase;
    private Employee employee;

    private int securityLvl;
    private static String masterPassword = Menu.getMasterPassword();

    /**
     * Constructor for objects of class PurchaseUI
     */
    public PurchaseUI()
    {
        purchaseCtr = new PurchaseCtr();
        productCtr = new ProductCtr();
        customerCtr = new CustomerCtr();

    }

    public void addPurchase(Purchase purchase) 
    {
        purchaseCtr.addPurchase(purchase);
    }

    public Purchase findPurchase(String id) 
    {
        return purchaseCtr.findPurchase(id);
    }

    public void updatePurchase(Purchase purchase, String id, String date) 
    {
        purchaseCtr.updatePurchase(purchase,id,date);
    }

    public void deletePurchase(Purchase purchase) 
    {
        purchaseCtr.deletePurchase(purchase);
    }

    public void addItem(Purchase purchase, String barcode, int quantity) 
    {
        purchaseCtr.addItem(purchase, barcode,quantity);
    }

    public void removeItem(Purchase purchase, String barcode) 
    {
        purchaseCtr.removeItem(purchase, barcode);
    }

    public void setEmployee(Employee employee) 
    {
        this.employee = employee;
    } 

    public void setSecurityLvl(int securityLvl) 
    {
        this.securityLvl = securityLvl;
    }

    public void setMasterPassword(String password) 
    {
        this.masterPassword = password;
    }

    public void setDispatchDate(Purchase purchase, String dispatchDate) 
    {
        purchaseCtr.setDispatchDate(purchase, dispatchDate);
    }

    public void setDeliveryDate(Purchase purchase, String deliveryDate) 
    {
        purchaseCtr.setDeliveryDate(purchase, deliveryDate);
    }

    private int getChoice()
    {
        Scanner keyboard = new Scanner(System.in);
        int choice = keyboard.nextInt();

        return choice;
    }

    // Sales menu loop
    public void menuStart() 
    {
        boolean exit = false;
        String print = null;
        while(!exit) 
        {
            writeMenu(print);
            int choice = getChoice();

            if(choice == 1) 
            {
                print = newSaleMenu();
            }
            else if(choice == 2)
            {
                print = findEditMenu();
            }
            else if(choice == 0)
            {
                exit = true;
            }
            else 
            {
                print = "ERROR!";
            }

        }
    }

    public void writeMenu(String print) 
    {
        System.out.println("\f *** Sales ***");
        System.out.println(" (1)New");
        System.out.println(" (2)Find / Edit");
        System.out.println(" (0)Back");

        if(print != null) 
        {
            System.out.println("\n " + print);

        }
        System.out.print("\n Make your choice: ");
    }

    // NEW SALE Menu
    public String newSaleMenu() 
    {
        String print = null;
        System.out.println("Enter new purchase id: ");
        Scanner sc = new Scanner(System.in);
        String id = sc.nextLine();
        if(!purchaseIdExists(id)) {

            DateFormat df = new SimpleDateFormat("dd/MM/yy HH:mm:ss");
            Date dateobj = new Date();
            String date = df.format(dateobj);

            purchase = null;
            purchase = new Purchase(id,date);
            purchase.setEmployee(employee);

            boolean exit = false;
            
            while(!exit) 
            {
                writeNewSaleMenu(print);
                int choice = getChoice();

                if(choice == 1) 
                {
                    print = this.startAddItem();
                }
                else if(choice == 2)
                {
                    print = this.startRemoveItem();
                }
                else if(choice == 3)
                {
                    print = this.startSetCustomer();
                }
                else if(choice == 4)
                {
                    print = this.startSetDiscount();
                }
                else if(choice == 5)
                {
                    print = this.startSaveOffer();
                }
                else if(choice == 6)
                {
                    print = this.startDelivery();                
                }
                else if(choice == 7)
                {
                    print = this.startConfirmSale();
                }
                else if(choice == 0)
                {
                    exit = true;
                }
                else 
                {
                    print = "ERROR!";
                }

            }
        }
        else 
        {
            print = "Sale with that ID already exists.";
        }
        return print;
    }

    private boolean purchaseIdExists(String id) 
    {

        boolean result = false;
        int counter = 0;
        while(result == false && counter < purchaseCtr.getPurchaseList().size()) 
        {
            if(purchaseCtr.getPurchaseList().get(counter).getId().equals(id))
            {
                result = true;
            }
            else 
            {
                counter++;
            }

        }
        return result;

    }

    public void writeNewSaleMenu(String print) 
    {
        System.out.println("\f *** SALE ID: " + purchase.getId() + " ***");
        System.out.println(" (1)Add item");
        System.out.println(" (2)Remove item");
        System.out.println(" (3)Set customer");
        System.out.println(" (4)Set discount");
        System.out.println(" (5)Save as offer");
        System.out.println(" (6)Delivery");
        System.out.println(" (7)Confirm sale");
        System.out.println(" (0)Back");

        if(print != null) 
        {
            System.out.println("\n " + print);

        }
        System.out.print("\n Make your choice: ");
    }

    // Add item
    public String startAddItem() 
    {
        String print = null;

        System.out.println("\nEnter barcode: ");        
        Scanner sc = new Scanner(System.in);
        String barcode = sc.next();

        System.out.println("\nEnter quantity: ");
        int quantity = 1;
        quantity = sc.nextInt();

        Product foundProduct = productCtr.findProduct(barcode);
        if(foundProduct != null) {
            if(quantity > foundProduct.getStockAmt()) 
            {
                print = "Error: Not enough products in stock.";
            }
            else {

                LineItem lineItem = new LineItem(foundProduct,quantity);
                purchase.addLineItem(lineItem);
                print = "Added item:" + "\n"
                + "Name: " + foundProduct.getName() + "\n"
                + "Description: " + foundProduct.getDescription() + "\n"
                + "Quantity: " + quantity + "\n"
                + "--" + "\n"
                + "Subtotal:  kr " + purchase.subtotal();

            }
        }
        else 
        {
            print = "Error: Product does not exist.";
        }
        return print;
    }

    // Remove item
    public String startRemoveItem() 
    {
        String print = null;

        System.out.println("\nEnter barcode: ");        
        Scanner sc = new Scanner(System.in);
        String barcode = sc.next();       

        Product foundProduct = productCtr.findProduct(barcode);
        if(foundProduct != null) 
        {
            removeItem(purchase,barcode);
            print = "Removed item:" + "\n"
            + "Name: " + foundProduct.getName() + "\n"
            + "Description: " + foundProduct.getDescription() + "\n";

        }
        else 
        {
            print = "Error: Product does not exist.";
        }
        return print;
    }

    // Set customer
    public String startSetCustomer() 
    {
        String print = null;

        System.out.println("Enter customer ID: ");
        Scanner sc = new Scanner(System.in);
        String id = sc.next();

        Customer foundCustomer = customerCtr.findCustomer(id);
        if(foundCustomer != null) 
        {
            purchase.setCustomer(foundCustomer);
            print = "Customer successfully assigned to the sale:" + "\n"
            + " Name: " + foundCustomer.getName() + "\n"
            + " Address: " + foundCustomer.getAddress() + "\n"
            + " Phone: " + foundCustomer.getPhone() + "\n"
            + " E-mail: " + foundCustomer.getEmail() + "\n"
            + " Type: " + foundCustomer.getType();
        }
        else 
        {
            print = "Error: Customer does not exist.";
        }
        return print;
    }

    // Set discount
    public String startSetDiscount() 
    {
        String print = null;

        boolean access = false;

        Scanner sc = new Scanner(System.in);

        if(securityLvl < 2) 
        {
            while(access == false) 
            {
                System.out.println("ACCESS DENIED! Enter password: ");                
                String password = sc.nextLine();

                if(password.equals(masterPassword)) 
                {
                    access = true;
                }
            } 

        }
        else 
        {
            access = true;
        }

        if(access == true) 
        {
            System.out.println(" Current discount: " + purchase.getDiscount() + "%");
            System.out.println(" Enter new discount (maximum " + Purchase.getMaxDiscount() + "%): ");
            int discount = sc.nextInt();
            purchase.setDiscount(discount);

            print = "Discount for sale #" + purchase.getId() + " has been set to " + purchase.getDiscount() + "%." + "\n"
            + " Updated price: kr" + purchase.subtotal();

        }
        return print;
    }

    // Save as offer
    public String startSaveOffer() 
    {
        String print = null;

        purchase.setState("offer");
        addPurchase(purchase);

        print = " Sale #" + purchase.getId() + " has been saved as an offer.";
        return print;
    }

    // Save as delivery
    public String startDelivery() 
    {
        String print = null;

        if(purchase.getCustomer() != null) 
        {
            purchase.setState("delivery");
            addPurchase(purchase);

            print = " Sale #" + purchase.getId() + " has been saved and marked to be delivered to:" + "\n"
            + " Name: " + purchase.getCustomer().getName() + "\n"
            + " Address: " + purchase.getCustomer().getAddress() + "\n"
            + " Phone: " + purchase.getCustomer().getPhone() + "\n"
            + " E-mail: " + purchase.getCustomer().getEmail();

        }
        else 
        {
            print = "Error: Customer not registered.";
        }

        return print;
    }

    public String startConfirmSale() 
    {
        String print = null;

        purchase.setState("finalized");

        for(LineItem lineItem : purchase.getLineItemList()) 
        {
            lineItem.getProduct().updateStock(lineItem.getQuantity());
            lineItem.getProduct().updateAmountSold(lineItem.getQuantity());
        }

        if(purchase.getCustomer() != null) 
        {
            purchase.getCustomer().setTotalAmount(purchase.subtotal());
        }        
        purchase.getEmployee().setTotalAmount(purchase.subtotal());

        addPurchase(purchase);
        print = " Sale #" + purchase.getId() + " has been finalized and saved.";
        return print;
    }

    // Find/Edit Menu 
    public String findEditMenu() 
    {
        String print = null;

        boolean exit = false;
        print = purchaseFindStart();
        if(purchase == null) 
        {
            exit = true;
        }
        while(!exit) 
        {
            writeFindEditMenu(print);
            int choice = getChoice();

            if(choice == 1) 
            {
                print = purchasePrintInfo();
            }
            else if(purchase.getState().equals("offer")) {
                if(choice == 2)
                {
                    print = startSetDiscount();

                }
                else if(choice == 3) 
                {
                    print = startSetCustomer();
                }
                else if(choice == 4) 
                {
                    print = startDelivery();
                }
                else if(choice == 5) 
                {
                    print = startConfirmSale();
                }
                else if(choice == 6) 
                {
                    print = startDeletePurchase();
                }
            }
            else if(purchase.getState().equals("delivery")) 
            {
                if(choice == 2)
                {
                    print = startSetDispatchDate();

                }
                else if(choice == 3) 
                {
                    print = startMarkDelivered();
                }
                else if(choice == 4 && securityLvl == 3) 
                {
                    print = startDeletePurchase();
                }
            }
            else if(securityLvl == 3) 
            {
                if(choice == 2)
                {
                    print = startDeletePurchase();

                }
            }

            if(choice == 0) 
            {
                print = null;
                exit = true;
            }
        }

        return print;
    }

    private void writeFindEditMenu(String print) 
    {
        System.out.println("\f *** SALE ID: " + purchase.getId() + " ***");
        System.out.println(" (1)Show information");
        if(purchase.getState().equals("offer")) {            
            System.out.println(" (2)Update discount");
            System.out.println(" (3)Set customer");
            System.out.println(" (4)Mark for delivery");
            System.out.println(" (5)Confirm sale");
            System.out.println(" (6)Delete");
        }
        else if(purchase.getState().equals("delivery")) 
        {
            System.out.println(" (2)Set dispatch date");
            System.out.println(" (3)Mark as delivered");
            if (securityLvl == 3)
            {
                System.out.println(" (4)Delete");
            }
        }
        else if (securityLvl == 3)
        {
            System.out.println(" (2) Delete");
        }

        System.out.println(" (0)Back");
        if(print != null) 
        {
            System.out.println("\n " + print);

        }
        System.out.print("\n Make your choice: ");
    }

    public String purchasePrintInfo() 
    {
        String print = null;
        print = " #Sale: #" + "\n" 
        + "  ID: " + purchase.getId() + "\n"
        + "  Date: " + purchase.getDate() + "\n";
        if(purchase.getCustomer() != null) {
            print += "  Customer ID: " + purchase.getCustomer().getId() + "\n"
            + "  Customer name: " + purchase.getCustomer().getName() + "\n";
        }
        print += "  STATE: " + purchase.getState() + "\n";
        if(purchase.getDispatchDate() != null) 
        {
            print += "  Dispatched on: " + purchase.getDispatchDate() + "\n";
        }
        if(purchase.getDeliveryDate() != null) 
        {
            print += "  Delivered on: " + purchase.getDeliveryDate() + "\n";
        }
        print += "  -- \n"
        + "  SUMMARY:";

        int counter = 1;
        for(LineItem lineItem : purchase.getLineItemList()) 
        {
            print += "\n  " + counter + ": " + lineItem.getProduct().getName() + " x" + lineItem.getQuantity();
            counter++;
        }

        print += "\n  -- \n"
        + "  Discount: " + purchase.getDiscount() + "%\n"
        + "  -- \n"
        + "  Total: kr" + purchase.subtotal();
        return print;
    }

    public String purchaseFindStart() 
    {

        String print = null;
        System.out.print("\nEnter id: ");

        Scanner sc = new Scanner(System.in);
        String id = sc.next();
        purchase = null;
        purchase = findPurchase(id);
        if(purchase == null) 
        {
            print = "ERROR: Sale not found.";
        }
        return print;

    }

    public String startDeletePurchase() 
    {
        deletePurchase(purchase);
        return "Sale #" + purchase.getId() + " has been deleted.";
    }

    public String startSetDispatchDate() 
    {
        String print = null;

        System.out.println("Enter dispatch date [DD-MM-YYYY]: ");
        Scanner sc = new Scanner(System.in);
        String dispatchDate = sc.next();

        purchase.setDispatchDate(dispatchDate);

        print = "Dispatch date has been set to " + dispatchDate + ".";
        return print;
    }

    public String startMarkDelivered() 
    {
        String print = null;

        System.out.println("Enter delivery date [DD-MM-YYYY]: ");
        Scanner sc = new Scanner(System.in);
        String deliveryDate = sc.next();

        purchase.setDeliveryDate(deliveryDate);
        purchase.setState("finalized");

        print = "Sale has been marked as delivered on " + deliveryDate + ".";
        return print;
    }
}
